#include "StdAfx.h"
#include "PictureDrawThread.h"
#include "StdAfx.h"
#include "Picture.h"
#include <time.h>
#include <stdlib.h>
#include <stdio.h>

PictureDrawThread::PictureDrawThread(int loopCount, Picture *picture, Mutex^ quadrantMutex1, Mutex^ quadrantMutex2, Mutex^ quadrantMutex3, Mutex^ quadrantMutex4)
{
	//mutex for each quadrant
	this->quadrantMutex1 = quadrantMutex1;
	this->quadrantMutex2 = quadrantMutex2;
	this->quadrantMutex3 = quadrantMutex3;
	this->quadrantMutex4 = quadrantMutex4;

	//picture to work with
	this->picture = picture;

	//set up number of loops
	this->loopCount = loopCount;
}

void PictureDrawThread::MutexDraw()
{

	//set randomizer seed 
	srand((unsigned) time(NULL));

	//cache height/width in integers for calculations
	int height = this->picture->pHeight;
	int width = this->picture->pWidth;

	//calculate quadrant sizes
	int quadrant = 0;
	int upperQuadrantHeight = height / 2;
	int bottomQuadrantHeight = height-upperQuadrantHeight;
	int leftQuadrantWidth = width / 2;
	int rightQuadrantWidth = width-leftQuadrantWidth;

	//for each quadrant borders are being calculated
	int xLeft = 0;
	int xRight = 0;
	int yTop = 0;
	int yBottom = 0;

	//random rectangle size variables
	int randomX0;
	int randomY0;
	int randomX1;
	int randomY1;

	//random color + alpha variables
	unsigned char randomColorRed;
	unsigned char randomColorGreen;
	unsigned char randomColorBlue;
	unsigned char randomAlpha;

	//loop
	for (int i = 0; i < loopCount; i++)
	{
	
		//random quadrant to fill
		quadrant = rand() % 5;

		//block current thread + set up rectangle position for the chosen quadrant


		//upper left quadrant
		if (quadrant == 0)
		{
			xLeft = yTop = 0;
			xRight = leftQuadrantWidth;
			yBottom = upperQuadrantHeight;
			quadrantMutex1->WaitOne();
		}
		//upper right quadrant
		else if (quadrant == 1)
		{
			xLeft = leftQuadrantWidth;
			xRight = leftQuadrantWidth + rightQuadrantWidth;
			yTop = 0;
			yBottom = upperQuadrantHeight;
			quadrantMutex2->WaitOne();
		}
		//lower left quadrant
		else if (quadrant == 2)
		{
			xLeft = 0;
			xRight = leftQuadrantWidth;
			yTop = upperQuadrantHeight;
			yBottom = upperQuadrantHeight + bottomQuadrantHeight;
			quadrantMutex3->WaitOne();
		}
		//lower right quadrant
		else if (quadrant == 3)
		{ 
			xLeft = leftQuadrantWidth;
			xRight = leftQuadrantWidth + rightQuadrantWidth;
			yTop = upperQuadrantHeight;
			yBottom = upperQuadrantHeight + bottomQuadrantHeight;
			quadrantMutex4->WaitOne();
		}
		//all quadrants
		else
		{
			quadrantMutex1->WaitOne();
			quadrantMutex2->WaitOne();
			quadrantMutex3->WaitOne();
			quadrantMutex4->WaitOne();

			xLeft = rand() % (leftQuadrantWidth);
			xRight = rand() % (leftQuadrantWidth) + leftQuadrantWidth;
			yTop = rand() % (upperQuadrantHeight);
			yBottom = rand() % (upperQuadrantHeight) + upperQuadrantHeight;

		}

		//calculate borders for the drawing of the quadrant-overlapping rectangle
		if (quadrant < 4)
		{
			//(re)setting random position WITHIN the chosen quadrant
			randomX0 = rand() % (xRight - xLeft) + xLeft;
			randomX1 = rand() % (xRight - xLeft) + xLeft;
			randomY0 = rand() % (yBottom - yTop) + yTop;
			randomY1 = rand() % (yBottom - yTop) + yTop;

			//setting up 
			xLeft = (randomX0 <= randomX1) ? randomX0 : randomX1;
			xRight = (randomX1 > randomX0) ? randomX1 : randomX0;
			yTop = (randomY0 <= randomY1) ? randomY0 : randomY1;
			yBottom = (randomY1 > randomY0) ? randomY1 : randomY0;
		}


		//(re)setting the random colors + alpha value
		randomColorRed = rand() % 255;
		randomColorGreen = rand() % 255;
		randomColorBlue = rand() % 255;
		randomAlpha = rand() % 255;

		this->picture->drawRectangle(xLeft,yTop,xRight,yBottom,randomColorRed,randomColorGreen,randomColorBlue,randomAlpha);

		if (quadrant == 0)
			quadrantMutex1->ReleaseMutex();
		else if (quadrant == 1)
			quadrantMutex2->ReleaseMutex();
		else if (quadrant == 2)
			quadrantMutex3->ReleaseMutex();
		else if (quadrant == 3)
			quadrantMutex4->ReleaseMutex();
		else
		{
			quadrantMutex1->ReleaseMutex();
			quadrantMutex2->ReleaseMutex();
			quadrantMutex3->ReleaseMutex();
			quadrantMutex4->ReleaseMutex();
		}
		
	}
}